package base

import (
	"context"
	"database/sql"
	"errors"
	"git.mycaigou.com/gfyx/micro-gfyx-oppty-service/infrastructure/common/errcode"
	"git.mycaigou.com/gfyx/micro-gfyx-oppty-service/infrastructure/common/utils"
	"git.mycaigou.com/gfyx/micro-gfyx-oppty-service/infrastructure/dto/base"
	"git.mycaigou.com/gfyx/micro-gfyx-oppty-service/infrastructure/repository/base/org"
	"git.mycaigou.com/gfyx/micro-gfyx-oppty-service/infrastructure/repository/base/role"
	"git.mycaigou.com/gfyx/micro-gfyx-oppty-service/infrastructure/repository/base/user"
	basePb "git.mycaigou.com/gfyx/micro-gfyx-oppty-service/proto/micro_gfyx_oppty_service_proto/micro-gfyx-oppty-service/base"
	userService "git.mycaigou.com/gfyx/micro-gfyx-oppty-service/service/base/user"
	"git.myscrm.cn/golang/common/ykerrcode"
	"git.myscrm.cn/golang/stark/v4"
	"time"
)

type baseUserServer struct {
	baseUserService userService.UserServiceIface
}

func NewBaseUserServer(
	baseUserService userService.UserServiceIface) basePb.BaseUserServiceServer {
	return &baseUserServer{
		baseUserService: baseUserService,
	}
}

func (s *baseUserServer) getPage(page *basePb.BasePage) *utils.PageInfo {
	if page == nil {
		page = &basePb.BasePage{
			Page:     1,
			PageSize: 10,
		}
	}

	newPage := &utils.PageInfo{
		Page:     int(page.Page),
		PageSize: int(page.PageSize),
	}

	return newPage
}

// UserList 用户列表
func (s *baseUserServer) UserList(ctx context.Context, req *basePb.UserListRequest) (*basePb.UserListResponse, error) {
	response := &basePb.UserListResponse{}
	if req.OrgId == 0 {
		return response, ykerrcode.TogRPCError(ykerrcode.INVALID_PARAMS, "部门编号为空")
	}

	if (req.Status < 0) || (req.Status > 2) {
		return response, ykerrcode.TogRPCError(ykerrcode.INVALID_PARAMS, "账号状态参数错误")
	}

	page := s.getPage(req.Page)
	userList, page, err := s.baseUserService.UserList(ctx, req.OrgId, req.Status, req.Keyword, page)
	if err != nil {
		return response, errcode.CTogRPCError(err)
	}

	userIds := make([]int64, 0)
	for _, userItem := range userList {
		userIds = append(userIds, userItem.Id)
	}

	userOrgMap, userToOrgRelMap, userRoleMap, err := s.baseUserService.ListByUserIds(ctx, userIds)
	if err != nil {
		return response, errcode.CTogRPCError(err)
	}

	response = s.format(userList, page, userOrgMap, userToOrgRelMap, userRoleMap)
	return response, nil
}

func (s *baseUserServer) format(
	userList []*user.GfyxUserPo,
	page *utils.PageInfo,
	userOrgMap map[int64][]*org.GfyOrganizationPo,
	userToOrgRelMap map[int64][]*user.GfyxUserOrganizationRelationPo,
	userRoleMap map[int64][]*role.GfyRolePo,
) *basePb.UserListResponse {
	response := &basePb.UserListResponse{}
	response.List = make([]*basePb.BaseUser, 0)
	for _, item := range userList {
		orgItem, ok := userOrgMap[item.Id]
		fullNameArray := make([]string, 0)
		if ok {
			for _, item := range orgItem {
				fullNameArray = append(fullNameArray, item.FullName)
			}
		}

		roleItem, ok := userRoleMap[item.Id]
		roles := make([]*basePb.RoleItem, 0)
		if ok {
			for _, item := range roleItem {
				roles = append(roles, &basePb.RoleItem{Id: item.Id, RoleName: item.Name})
			}
		}

		orgs := make([]*basePb.OrgItem, 0)
		userOrgRelArray, ok1 := userToOrgRelMap[item.Id]
		if ok1 {
			for _, uor := range userOrgRelArray {
				orgs = append(orgs, &basePb.OrgItem{
					Id: uor.OrganizationId,
				})
			}
		}

		response.List = append(response.List, &basePb.BaseUser{
			Id:            item.Id,
			UserName:      item.Name,
			Position:      item.Position,
			Mobile:        item.Mobile,
			Email:         item.Email,
			Status:        item.Status,
			Uid:           item.Uid,
			Orgs:          orgs,
			Roles:         roles,
			FullNameArray: fullNameArray,
			CreatedOn:     item.CreatedOn.Format("2006-01-02 15:04:05"),
			ModifiedOn:    item.ModifiedOn.Format("2006-01-02 15:04:05"),
		})
	}

	response.Page = &basePb.BasePage{
		Page:     int32(page.Page),
		PageSize: int32(page.PageSize),
		Total:    int32(page.Total),
	}

	return response
}

// UserSave 用户增加/修改
func (s *baseUserServer) UserSave(ctx context.Context, req *basePb.UserSaveRequest) (*basePb.UserSaveResponse, error) {
	response := &basePb.UserSaveResponse{}
	if req.User == nil {
		return response, ykerrcode.TogRPCError(ykerrcode.INVALID_PARAMS, "参数为空")
	}

	params := req.User
	if params.UserName == "" || params.Mobile == "" || len(params.Mobile) != 11 {
		return response, ykerrcode.TogRPCError(ykerrcode.INVALID_PARAMS, "缺少必填参数")
	}

	if len(params.Roles) == 0 {
		return response, ykerrcode.TogRPCError(ykerrcode.INVALID_PARAMS, "缺少角色参数")
	}

	if len(params.Orgs) == 0 {
		return response, ykerrcode.TogRPCError(ykerrcode.INVALID_PARAMS, "缺少组织参数")
	}

	userObj := &user.GfyxUserPo{
		Id:       params.Id,
		Name:     params.UserName,
		Mobile:   params.Mobile,
		Email:    params.Email,
		Position: params.Position,
		Password: params.Passwd,
		Source:   1,
		Status:   params.Status,
		LastSetPasswordTime: sql.NullTime{
			Valid: false,
		},
		CreatedOn:  time.Now(),
		CreatedBy:  "",
		ModifiedOn: time.Now(),
		ModifiedBy: "",
	}

	roleIds := make([]int64, 0)
	orgIds := make([]int64, 0)
	for _, roleItem := range params.Roles {
		roleIds = append(roleIds, roleItem.Id)
	}
	for _, orgItem := range params.Orgs {
		orgIds = append(orgIds, orgItem.Id)
	}
	userId, err := s.baseUserService.UserSave(ctx, userObj, orgIds, roleIds)
	if err != nil {
		stark.Logger.Infof(ctx, "UserSave-err: %+v", err)
		return response, errcode.CTogRPCError(err)
	}

	response.UserId = userId

	return response, nil
}

// UserDelete 删除用户
func (s *baseUserServer) UserDelete(ctx context.Context, req *basePb.UserDeleteRequest) (*basePb.UserDeleteResponse, error) {
	response := &basePb.UserDeleteResponse{}
	//if (req.LeaveUserId == 0) || (req.ReceiveUserId == 0) {
	//	return response, ykerrcode.TogRPCError(ykerrcode.INVALID_PARAMS, "参数为空")
	//}

	if req.LeaveUserId == 0 {
		return response, ykerrcode.TogRPCError(ykerrcode.INVALID_PARAMS, "参数为空")
	}

	// 1. 工作交接
	// TODO

	// 2. 删除用户
	userId, err := s.baseUserService.UserDelete(ctx, req.LeaveUserId)
	if err != nil {
		stark.Logger.Infof(ctx, "UserDelete-err: %+v, req: %+v", err, req)
		return response, errcode.CTogRPCError(err)
	}

	response.UserId = userId

	return response, nil
}

// UserForbid 禁止用户
func (s *baseUserServer) UserForbid(ctx context.Context, req *basePb.UserForbidRequest) (*basePb.UserForbidResponse, error) {
	response := &basePb.UserForbidResponse{}
	if req.UserId == 0 {
		return response, ykerrcode.TogRPCError(ykerrcode.INVALID_PARAMS, "用户编号为空")
	}

	if (req.Status < 1) || (req.Status > 2) {
		return response, ykerrcode.TogRPCError(ykerrcode.INVALID_PARAMS, "状态字段错误")
	}

	_, err := s.baseUserService.UserForbid(ctx, req.UserId, req.Status)
	if err != nil {
		stark.Logger.Infof(ctx, "UserForbid-err: %+v, req: %+v", err, req)
		return response, errcode.CTogRPCError(err)
	}

	response.IsSuccess = true

	return response, nil
}

// UserAuthRoles 账号授权
func (s *baseUserServer) UserAuthRoles(ctx context.Context, req *basePb.UserAuthRolesRequest) (*basePb.UserAuthRolesResponse, error) {
	response := &basePb.UserAuthRolesResponse{}
	if (req.UserId == 0) || (len(req.RoleIds) == 0) {
		return response, ykerrcode.TogRPCError(ykerrcode.INVALID_PARAMS, "用户编号为空")
	}

	err := s.baseUserService.UserAuthRoles(ctx, req.UserId, req.RoleIds)
	if err != nil {
		stark.Logger.Infof(ctx, "UserAuthRoles-err: %+v, req: %+v", err, req)
		return response, errcode.CTogRPCError(err)
	}

	response.IsSuccess = true

	return response, nil
}

// ImportUsers 导入用户
func (s *baseUserServer) ImportUsers(ctx context.Context, req *basePb.UserImportUsersRequest) (*basePb.UserImportUsersResponse, error) {
	if req.List == nil || len(req.List) == 0 {
		return nil, ykerrcode.TogRPCError(ykerrcode.INVALID_PARAMS, "导入用户为空")
	}

	userList := []*base.ImportUserDto{}
	for _, item := range req.List {
		userDto := &base.ImportUserDto{
			UserName:         item.UserName,
			Position:         item.Position,
			Email:            item.Email,
			Mobile:           item.Mobile,
			Passwd:           item.Passwd,
			Role:             item.Role,
			OrgFullName:      item.OrgFullName,
			DepartmentHeader: item.DepartmentHeader,
		}

		userList = append(userList, userDto)
	}
	resp, err := s.baseUserService.ImportUsers(ctx, userList)
	if err != nil {
		stark.Logger.Errorf(ctx, "ImportUsers-err: %+v, req: %+v", err, req)
		return resp, errcode.CTogRPCError(err)
	}

	return resp, nil
}

// UserInfo  获取登录用户
func (s *baseUserServer) UserInfo(ctx context.Context, request *basePb.UserInfoRequest) (*basePb.UserInfoResponse, error) {
	resp, err := s.baseUserService.UserInfo(ctx, *request)
	if err != nil {
		stark.Logger.Errorf(ctx, "grpc UserInfo request:%+v, err:%s", request, err)
		return nil, err
	}
	stark.Logger.Infof(ctx, "grpc UserInfo request:%+v, response:%#v", request, resp)
	return resp, nil
}

// ResetPassword 设置用户密码
func (s *baseUserServer) ResetPassword(ctx context.Context, request *basePb.ResetPasswordRequest) (*basePb.ResetPasswordResponse, error) {
	resp, err := s.baseUserService.SetPassword(ctx, *request)
	if err != nil {
		stark.Logger.Errorf(ctx, "grpc SetPassword request:%+v, err:%s", request, err)
		return resp, errcode.CTogRPCError(err)
	}
	stark.Logger.Infof(ctx, "grpc SetPassword request:%+v, response:%#v", request, resp)
	return resp, nil
}

// UserDetail 用户详情
func (s *baseUserServer) UserDetail(ctx context.Context, req *basePb.UserDetailRequest) (*basePb.UserDetailResponse, error) {
	var response = &basePb.UserDetailResponse{}
	if req.Id == 0 {
		return response, ykerrcode.TogRPCError(ykerrcode.INVALID_PARAMS, "状态字段错误")
	}

	userDetail, orgList, roleList, err := s.baseUserService.UserDetail(ctx, req.Id)
	if err != nil {
		stark.Logger.Errorf(ctx, "grpc UserDetail request:%+v, err:%s", req, err)
		return response, errcode.CTogRPCError(err)
	}

	orgs := make([]*basePb.OrgItem, 0)
	roles := make([]*basePb.RoleItem, 0)
	if len(orgList) != 0 {
		for _, o := range orgList {
			orgs = append(orgs, &basePb.OrgItem{
				ParentId: o.ParentId,
				OrgName:  o.Name,
				Id:       o.Id,
				FullName: o.FullName,
				//AreaCodes: o.AreaCodes,
			})
		}
	}

	if len(roleList) != 0 {
		for _, o := range roleList {
			roles = append(roles, &basePb.RoleItem{
				Id:       o.Id,
				RoleName: o.Name,
			})
		}
	}

	response.User = &basePb.BaseUser{
		Id:         userDetail.Id,
		UserName:   userDetail.Name,
		Position:   userDetail.Position,
		Mobile:     userDetail.Mobile,
		Email:      userDetail.Email,
		Status:     userDetail.Status,
		Orgs:       orgs,
		Roles:      roles,
		Uid:        userDetail.Uid,
		CreatedOn:  userDetail.CreatedOn.Format("2006-01-02 15:04:05"),
		ModifiedOn: userDetail.ModifiedOn.Format("2006-01-02 15:04:05"),
	}

	return response, nil
}

// UserSetDepartmentHeader 设置/取消负责人
func (s *baseUserServer) UserSetDepartmentHeader(ctx context.Context, req *basePb.UserSetDepartmentHeaderRequest) (*basePb.UserSetDepartmentHeaderResponse, error) {
	var response = &basePb.UserSetDepartmentHeaderResponse{}

	if req.OrgId == 0 {
		return response, ykerrcode.TogRPCError(ykerrcode.INVALID_PARAMS, "用户组织编号为空")
	}
	err := s.baseUserService.SetDepartmentHeader(ctx, req.UserId, req.OrgId)
	if err != nil {
		stark.Logger.Errorf(ctx, "grpc UserDetail request:%+v, err:%s", req, err)
		return response, errcode.CTogRPCError(err)
	}

	response.IsSuccess = true
	return response, nil
}

// SyncUserInfo 同步建模用户
func (s *baseUserServer) SyncUserInfo(ctx context.Context, request *basePb.BaseOldUserSyncRequest) (*basePb.BaseOldUserSyncResponse, error) {
	resp, err := s.baseUserService.SyncUserForJM(ctx, *request)
	if err != nil {
		return nil, err
	}
	return resp, nil
}

func (s *baseUserServer) GetAllUserList(ctx context.Context, request *basePb.EmptyRequest) (*basePb.GetAllUserListResponse, error) {
	count, list, err := s.baseUserService.GetAllUser(ctx)
	if err != nil {
		return nil, err
	}

	resp := &basePb.GetAllUserListResponse{
		List:  nil,
		Total: count,
	}
	for _, userPo := range list {
		resp.List = append(resp.List, &basePb.BaseUser{
			Id:            userPo.Id,
			UserName:      userPo.Name,
			Position:      userPo.Position,
			Mobile:        userPo.Mobile,
			Email:         userPo.Email,
			Status:        userPo.Status,
			Orgs:          nil,
			Roles:         nil,
			Passwd:        "",
			Uid:           userPo.Uid,
			FullNameArray: nil,
			CreatedOn:     userPo.CreatedOn.Format("2006-01-02 15:04:05"),
			ModifiedOn:    userPo.ModifiedOn.Format("2006-01-02 15:04:05"),
		})
	}

	return resp, nil
}

func (s *baseUserServer) GetAllUserWithOrganization(ctx context.Context, request *basePb.GetAllUserWithOrganizationRequest) (*basePb.GetAllUserWithOrganizationResponse, error) {
	resp, err := s.baseUserService.GetAllUserWithOrganization(ctx)
	if err != nil {
		return nil, err
	}
	return resp, nil
}

func (s *baseUserServer) GetUserIdUserUid(ctx context.Context, request *basePb.GetUserIdUserUidRequest) (*basePb.GetUserIdUserUidResponse, error) {
	if request.UserUid == "" {
		return nil, errors.New("用户uid不能为空")
	}
	gfyxUserPo, err := s.baseUserService.GetUserInfoByUserGuid(ctx, request.UserUid)
	if err != nil {
		return nil, err
	}
	if gfyxUserPo == nil || gfyxUserPo.Id == 0 {
		return nil, errors.New("用户不存在")
	}

	return &basePb.GetUserIdUserUidResponse{
		Id: gfyxUserPo.Id,
	}, nil
}

// GetMyResponsibleAreaUserList 获取我负责区域下的用户
func (s *baseUserServer) GetMyResponsibleAreaUserList(ctx context.Context, request *basePb.GetMyResponsibleAreaUserListRequest) (*basePb.GetMyResponsibleAreaUserListResponse, error) {
	list, err := s.baseUserService.GetMyResponsibleAreaUserList(ctx, request)
	if err != nil {
		return nil, err
	}
	return list, nil
}

// UpdateAdminPassword 获取我负责区域下的用户
func (s *baseUserServer) UpdateAdminPassword(ctx context.Context, request *basePb.UpdateAdminPasswordRequest) (*basePb.UpdateAdminPasswordResponse, error) {
	resp, err := s.baseUserService.UpdateAdminPassword(ctx, *request)
	if err != nil {
		stark.Logger.Errorf(ctx, "grpc UpdateAdminPassword request:%+v, err:%s", request, err)
		return resp, errcode.CTogRPCError(err)
	}
	stark.Logger.Infof(ctx, "grpc UpdateAdminPassword request:%+v, response:%#v", request, resp)
	return resp, nil
}
